#include "resumable.h"
#include <iostream>
#include <utility>

namespace wilson::sys
{
    resumable::resumable(::std::coroutine_handle<> h) noexcept
        : r_task{ h }, r_need_dest{ true }
    {
        
    }

    resumable::resumable(::std::function<void()> func) 
        : r_task{ func }, r_need_dest{ false }
    {
    }

    resumable::resumable(resumable&& other) noexcept
    {
        other.r_need_dest = false;
        r_task = ::std::move(other.r_task);
        other.r_task = ::std::coroutine_handle<>{};
        r_need_dest = true;
    }

    resumable& resumable::operator=(resumable&& other) noexcept
    {
        other.r_need_dest = false;
        r_task = ::std::move(other.r_task);
        other.r_task = ::std::coroutine_handle<>{};
        r_need_dest = true;
        return *this;
    }

    void resumable::exec()
    {
        if (r_task.index() == 0) // coro
        {
            auto& coro = get<0>(r_task);
            if (coro) [[likely]]
                coro.resume();
        }
        else // function
        {
            get<1>(r_task)();
        }
    }

    bool resumable::is_coro() const noexcept
    {
        return r_task.index() == 0 && get<0>(r_task);
    }
}
